package com.situ.mall.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.situ.mall.api.user.UserClient;
import com.situ.mall.common.constant.MqConstant;
import com.situ.mall.common.exception.SituException;
import com.situ.mall.common.util.MultiDelayMessage;
import com.situ.mall.common.util.Result;
import com.situ.mall.order.entity.query.OrderInfoQuery;
import com.situ.mall.order.entity.vo.OrderInfoVO;
import com.situ.mall.order.mapper.CartMapper;
import com.situ.mall.order.mapper.OrderItemMapper;
import com.situ.mall.order.pojo.vo.CartVO;
import com.situ.mall.order.service.ICartService;
import com.situ.mall.pojo.entity.order.OrderInfo;
import com.situ.mall.order.mapper.OrderInfoMapper;
import com.situ.mall.order.service.IOrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.situ.mall.pojo.entity.order.OrderItem;
import com.situ.mall.pojo.entity.user.User;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author Gao
 * @since 2024-10-16
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService {
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private ICartService  cartService;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserClient userClient;

    @Override
    public void add(OrderInfo orderInfo) {
        //orderInfo里面有userId和addressId

        //1.生成订单的编号order_no,规则使用：时间戳+随机生成数 生成订单   uuid
        //格式化随机数，确保有六位数字
        String random = String.format("%06d", new Random().nextInt(1000000));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String orderNo = simpleDateFormat.format(new Date()) + random;
        System.out.println("orderNo:" + orderNo);
        orderInfo.setOrderNo(orderNo);

        //2.查找购物车中用户要结算的商品，然后过滤出checked=1
        List<CartVO> cartVOList = cartService.selectByUserId(orderInfo.getUserId());
        cartVOList = cartVOList.stream().filter(cartVO -> cartVO.getChecked() == 1).collect(Collectors.toList());
        //3.没遍历一次cartVO，就往order_item表里面插入一条数据
        BigDecimal totalAmount = new BigDecimal(0);
        for (CartVO cartVO : cartVOList) {
            OrderItem orderItem = new OrderItem();
            //这个订单项属于哪个订单
            orderItem.setOrderNo(orderNo);
            orderItem.setProductId(cartVO.getProductId());
            orderItem.setProductName(cartVO.getProductName());
            orderItem.setProductImage(cartVO.getProductImage());
            orderItem.setQuantity(cartVO.getQuantity());
            orderItem.setUnitPrice(cartVO.getProductPrice());
            orderItemMapper.insert(orderItem);

            //order_item中商品总价格:价格*数量
            BigDecimal itemAmount = orderItem.getUnitPrice().multiply(new BigDecimal(orderItem.getQuantity()));
            totalAmount = totalAmount.add(itemAmount);

            //删除购物车里面已经买的这件商品
            cartMapper.deleteById(cartVO.getId());

            //生成订单减库存：feign远程调用product-service

        }


        orderInfo.setTotalAmount(totalAmount);
        orderInfoMapper.insert(orderInfo);

        //调用短信服务通知用户

        //延迟检查订单状态消息
        MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderInfo.getId(), 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L);
        int delayValue = msg.removeNextDelay().intValue();
        rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, MqConstant.DELAY_ORDER_ROUTING_KEY, msg, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setDelay(delayValue);
                return message;
            }
        });

    }

    @Override
    public IPage<OrderInfoVO> list(OrderInfoQuery orderInfoQuery) {
        IPage<OrderInfoVO> page = new Page<>(orderInfoQuery.getPage(), orderInfoQuery.getLimit());
        page = orderInfoMapper.list(page, orderInfoQuery);
        return page;
    }

    @Override
    public void cancelOrder(Long orderId) {
        UpdateWrapper<OrderInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("order_status", 5).eq("id", orderId);
        orderInfoMapper.update(updateWrapper);
    }

    @Override
    public void updateStatus(OrderInfo orderInfo) {
        UpdateWrapper<OrderInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("order_status", orderInfo.getOrderStatus()).eq("id", orderInfo.getId());
        orderInfoMapper.update(updateWrapper);
    }

    @Override
    public void payOrder(Long userId, Long orderId) {
        Result<User> result = userClient.selectById(userId);
        if (result.getCode() == 0) {
            User user = result.getData();
            OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
            if (user.getBalance().compareTo(orderInfo.getTotalAmount()) < 0) {
                throw new SituException("余额不足");
            }
            //更新余额
            BigDecimal balance = user.getBalance().subtract(orderInfo.getTotalAmount());
            userClient.updateBalance(userId, balance);
            //更新订单状态
            UpdateWrapper<OrderInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("order_status", 2).eq("id", orderId);
            orderInfoMapper.update(updateWrapper);
        }
    }
}
